/**
 * Misc functions as utility for all web client product. 
 * Not depends on any javascript framework
 * 
 * @auther Zihao.Jiang@gmail.com Copyright (c) 2013
 * 
 */

(function() {
    /**
     * Fix Function.bind. In some webkit browser it doesn't exists, but we need
     */
    if (!Function.prototype.bind) {
        Function.prototype.bind = function() {
            var __method = this;
            var args = Array.prototype.slice.call(arguments);
            var object = args.shift();
            return function() {
                return __method.apply(object, args.concat(Array.prototype.slice
                        .call(arguments)));
            };
        };
    }

    /**
     * Fix String function
     */
    if (!String.prototype.repeat) {
        String.prototype.repeat = function(l) {
            return new Array(l + 1).join(this);
        };
    }
    if (!String.prototype.endsWith) {
        String.prototype.endsWith = function(s) {
            if (s == null || s == "" || this.length == 0
                    || s.length > this.length)
                return false;
            if (this.substring(this.length - s.length) == s)
                return true;
            else
                return false;
            return true;
        };
    }
    if (!String.prototype.startsWith) {
        String.prototype.startsWith = function(s) {
            if (s == null || s == "" || this.length == 0
                    || s.length > this.length)
                return false;
            if (this.substr(0, s.length) == s)
                return true;
            else
                return false;
            return true;
        };
    }
    
    /**
     * For graphic. Format number with IT
     */
    function number_format(number, decimals, dec_point, thousands_sep) {
        //http://phpjs.org/functions/number_format/
        number = (number + '').replace(/[^0-9+\-Ee.]/g, '');
        var n = !isFinite(+number) ? 0 : +number, prec = !isFinite(+decimals) ? 0
                : Math.abs(decimals), sep = (typeof thousands_sep === 'undefined') ? ','
                : thousands_sep, dec = (typeof dec_point === 'undefined') ? '.'
                : dec_point, s = '', toFixedFix = function(n, prec) {
            var k = Math.pow(10, prec);
            return '' + Math.round(n * k) / k;
        };
        // Fix for IE parseFloat(0.55).toFixed(0) = 0;
        s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.');
        if (s[0].length > 3) {
            s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
        }
        if ((s[1] || '').length < prec) {
            s[1] = s[1] || '';
            s[1] += new Array(prec - s[1].length + 1).join('0');
        }
        return s.join(dec);
    }
    
    var di = [ [ 1e12, 'T' ], [ 1e9, 'G' ], [ 1e6, 'M' ], [ 1e3, 'K' ]];

    Number.prototype.fmtIT = function(suffix) {
        var val = this;
        for ( var i = 0; i < di.length; i++) {
            if (val >= di[i][0]) {
                if (val % di[i][0] == 0)
                    return number_format(val / di[i][0], 0) + di[i][1] + (suffix || '');
                else
                    return number_format(val / di[i][0], 1) + di[i][1] + (suffix || '');
            }
        }
        if (val*10 % 10 == 0)
            return number_format(val, 0) + (suffix || '');
        else
            return number_format(val, 1) + (suffix || '');
    };
    
    if (!Date.prototype.format) {
        /**
         * Format date
         * 
         * @param fmt
         *            (new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==>
         *            2006-07-02 08:09:04.423 (new Date()).Format("yyyy-M-d
         *            h:m:s.S") ==> 2006-7-2 8:9:4.18
         * @returns
         */
        Date.prototype.format = function(fmt) { // author: meizz
            var o = {
                "M+" : this.getMonth() + 1,
                "d+" : this.getDate(),
                "h+" : this.getHours(),
                "m+" : this.getMinutes(),
                "s+" : this.getSeconds(),
                "q+" : Math.floor((this.getMonth() + 3) / 3),
                "S" : this.getMilliseconds()
            };
            if (/(y+)/.test(fmt))
                fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "")
                        .substr(4 - RegExp.$1.length));
            for ( var k in o)
                if (new RegExp("(" + k + ")").test(fmt))
                    fmt = fmt.replace(RegExp.$1,
                            (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k])
                                    .substr(("" + o[k]).length)));
            return fmt;
        };
    }
    
    /**
     * Export: check_plugin
     */
    check_plugin = function (plugin_name) {
        var found = {};
        var version_reg = /[0-9]+/;

        /*
         * we don't support windows IE now
         */
        if (window.ActiveXObject) {
            //var nothing = {};
            return false;
        } else {
            var plugins = navigator.plugins;
            var reg = new RegExp(plugin_name);
            for (var i = 0; i < plugins.length; i++) {
                var reg_val = reg.exec(plugins[i].description);
                if (reg_val){
                    var plugin = reg_val[0].toLowerCase();
                    /*
                     * Search in version property, if not available concat name and description
                     * and search for a version number in there
                     */
                    var version = plugins[i].version ||
                        (plugins[i].name + ' ' + plugins[i].description);
                    var version_reg_val = version_reg.exec(version);
                    if (!found[plugin]) {
                        found[plugin] = (version_reg_val && version_reg_val[0]) || '';
                    }
                    return true;
                }
            }
        }

        return false;
    };
})();